from datetime import datetime
import uuid
from typing import List, Dict, Optional
import json

class Message:
    def __init__(self, content: str, role: str, timestamp: Optional[datetime] = None, message_id: Optional[str] = None):
        self.message_id = message_id or str(uuid.uuid4())
        self.content = content
        self.role = role
        self.timestamp = timestamp or datetime.now()
    
    def to_dict(self) -> Dict:
        return {
            'message_id': self.message_id,
            'content': self.content,
            'role': self.role,
            'timestamp': self.timestamp.isoformat()
        }

    @classmethod
    def from_dict(cls, data: Dict) -> 'Message':
        return cls(
            content=data['content'],
            role=data['role'],
            timestamp=datetime.fromisoformat(data['timestamp']) if 'timestamp' in data else None,
            message_id=data.get('message_id')
        )

class Conversation:
    def __init__(self, conversation_id: Optional[str] = None, title: Optional[str] = None):
        self.conversation_id = conversation_id or str(uuid.uuid4())
        self.title = title or "新对话"
        self.messages: List[Message] = []
        self.created_at = datetime.now()
        self.updated_at = datetime.now()
        
    def add_message(self, content: str, role: str) -> Message:
        message = Message(content, role)
        self.messages.append(message)
        self.updated_at = datetime.now()
        return message
    
    def get_messages(self) -> List[Dict]:
        return [msg.to_dict() for msg in self.messages]
    
    def clear(self) -> None:
        self.messages = []
        self.updated_at = datetime.now()
    
    def to_dict(self) -> Dict:
        return {
            'conversation_id': self.conversation_id,
            'title': self.title,
            'messages': self.get_messages(),
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }
    
    def to_json(self) -> str:
        return json.dumps(self.to_dict(), ensure_ascii=False)
    
    @classmethod
    def from_dict(cls, data: Dict) -> 'Conversation':
        conversation = cls(
            conversation_id=data.get('conversation_id'),
            title=data.get('title')
        )
        conversation.created_at = datetime.fromisoformat(data['created_at'])
        conversation.updated_at = datetime.fromisoformat(data['updated_at'])
        for msg_data in data.get('messages', []):
            message = Message.from_dict(msg_data)
            conversation.messages.append(message)
        return conversation

class ConversationManager:
    def __init__(self):
        self.conversations: Dict[str, Conversation] = {}
    
    def create_conversation(self, title: Optional[str] = None) -> Conversation:
        conversation = Conversation(title=title)
        self.conversations[conversation.conversation_id] = conversation
        return conversation
    
    def get_conversation(self, conversation_id: str) -> Optional[Conversation]:
        return self.conversations.get(conversation_id)
    
    def delete_conversation(self, conversation_id: str) -> bool:
        if conversation_id in self.conversations:
            del self.conversations[conversation_id]
            return True
        return False
    
    def get_all_conversations(self) -> List[Dict]:
        return [
            {
                'conversation_id': conv.conversation_id,
                'title': conv.title,
                'created_at': conv.created_at.isoformat(),
                'updated_at': conv.updated_at.isoformat(),
                'message_count': len(conv.messages)
            }
            for conv in self.conversations.values()
        ]
    
    def save_to_file(self, filepath: str) -> None:
        data = {
            conv_id: conv.to_dict()
            for conv_id, conv in self.conversations.items()
        }
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
    
    @classmethod
    def load_from_file(cls, filepath: str) -> 'ConversationManager':
        manager = cls()
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                data = json.load(f)
                for conv_id, conv_data in data.items():
                    conversation = Conversation.from_dict(conv_data)
                    manager.conversations[conv_id] = conversation
        except FileNotFoundError:
            pass
        return manager
